Suomi

Hyödynnä GraphQL-federaation teho skeemojen yhdistämisen avulla. Opi rakentamaan yhtenäinen GraphQL API useista palveluista, parantaen skaalautuvuutta ja ylläpidettävyyttä.

GraphQL-federaatio: Skeemojen yhdistäminen (Schema Stitching) - Kattava opas

Nykyaikaisen sovelluskehityksen jatkuvasti muuttuvassa maisemassa skaalautuvien ja ylläpidettävien arkkitehtuurien tarve on tullut ensiarvoisen tärkeäksi. Mikropalvelut, luontaisella modulaarisuudellaan ja itsenäisellä käyttöönotettavuudellaan, ovat nousseet suosituksi ratkaisuksi. Useiden mikropalveluiden hallinta voi kuitenkin tuoda mukanaan monimutkaisuutta, erityisesti kun tarkoituksena on tarjota yhtenäinen API asiakassovelluksille. Tässä kohtaa GraphQL-federaatio, ja erityisesti skeemojen yhdistäminen (Schema Stitching), astuu kuvaan.

Mitä on GraphQL-federaatio?

GraphQL-federaatio on tehokas arkkitehtuuri, joka mahdollistaa yhtenäisen GraphQL API:n rakentamisen useista taustalla olevista GraphQL-palveluista (jotka usein edustavat mikropalveluita). Se antaa kehittäjille mahdollisuuden hakea dataa eri palveluista ikään kuin ne olisivat yksi ainoa graafi, mikä yksinkertaistaa asiakaskokemusta ja vähentää tarvetta monimutkaiselle orkestrointilogiikalle asiakaspäässä.

GraphQL-federaatioon on kaksi pääasiallista lähestymistapaa:

Tämä artikkeli keskittyy skeemojen yhdistämiseen, tutkien sen käsitteitä, etuja, rajoituksia ja käytännön toteutusta.

Skeemojen yhdistämisen ymmärtäminen

Skeemojen yhdistäminen on prosessi, jossa useita GraphQL-skeemoja yhdistetään yhdeksi, yhtenäiseksi skeemaksi. Tämä yhtenäinen skeema toimii julkisivuna, joka piilottaa taustalla olevien palveluiden monimutkaisuuden asiakkaalta. Kun asiakas tekee pyynnön yhdistettyyn skeemaan, yhdyskäytävä reitittää pyynnön älykkäästi asianmukaiseen taustapalveluun (tai palveluihin), noutaa datan ja yhdistää tulokset ennen niiden palauttamista asiakkaalle.

Ajattele sitä näin: Sinulla on useita ravintoloita (palveluita), jotka ovat erikoistuneet eri keittiöihin. Skeemojen yhdistäminen on kuin yleismenu, joka yhdistää kaikki ruokalajit jokaisesta ravintolasta. Kun asiakas (client) tilaa yleismenusta, tilaus reititetään älykkäästi oikeisiin ravintolakeittiöihin, ruoka valmistetaan ja yhdistetään sitten yhdeksi toimitukseksi asiakkaalle.

Skeemojen yhdistämisen avainkäsitteet

Skeemojen yhdistämisen edut

Skeemojen yhdistäminen tarjoaa useita merkittäviä etuja organisaatioille, jotka käyttävät mikropalveluarkkitehtuuria:

Skeemojen yhdistämisen rajoitukset

Vaikka skeemojen yhdistäminen tarjoaa lukuisia etuja, on tärkeää olla tietoinen sen rajoituksista:

Skeemojen yhdistämisen käytännön toteutus

Käydään läpi yksinkertaistettu esimerkki siitä, miten Schema Stitching toteutetaan Node.js:llä ja graphql-tools-kirjastolla (suosittu valinta skeemojen yhdistämiseen). Tämä esimerkki sisältää kaksi mikropalvelua: Käyttäjäpalvelun ja Tuotepalvelun.

1. Määritä etäskeemat

Määritä ensin GraphQL-skeemat kullekin etäpalvelulle.

Käyttäjäpalvelu (user-service.js):


const { buildSchema } = require('graphql');

const userSchema = buildSchema(`
  type User {
    id: ID!
    name: String
    email: String
  }

  type Query {
    user(id: ID!): User
  }
`);

const users = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com' },
  { id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];

const userRoot = {
  user: (args) => users.find(user => user.id === args.id),
};

module.exports = {
  schema: userSchema,
  rootValue: userRoot,
};

Tuotepalvelu (product-service.js):


const { buildSchema } = require('graphql');

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Foreign key to User Service
  }

  type Query {
    product(id: ID!): Product
  }
`);

const products = [
  { id: '101', name: 'Laptop', price: 1200, userId: '1' },
  { id: '102', name: 'Smartphone', price: 800, userId: '2' },
];

const productRoot = {
  product: (args) => products.find(product => product.id === args.id),
};

module.exports = {
  schema: productSchema,
  rootValue: productRoot,
};

2. Luo yhdyskäytäväpalvelu

Luo nyt yhdyskäytäväpalvelu, joka yhdistää kaksi skeemaa.

Yhdyskäytäväpalvelu (gateway.js):


const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');

async function createRemoteSchema(uri) {
  const fetcher = async (params) => {
    const response = await fetch(uri, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });
    return response.json();
  };

  const schema = await introspectSchema(fetcher);
  return makeRemoteExecutableSchema({
    schema,
    fetcher,
  });
}

async function main() {
  const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
  const productSchema = await createRemoteSchema('http://localhost:4002/graphql');

  const stitchedSchema = stitchSchemas({
    subschemas: [
      { schema: userSchema },
      { schema: productSchema },
    ],
    typeDefs: `
      extend type Product {
        user: User
      }
    `,
    resolvers: {
      Product: {
        user: {
          selectionSet: `{ userId }`,
          resolve(product, args, context, info) {
            return info.mergeInfo.delegateToSchema({
              schema: userSchema,
              operation: 'query',
              fieldName: 'user',
              args: {
                id: product.userId,
              },
              context,
              info,
            });
          },
        },
      },
    },
  });

  const app = express();
  app.use('/graphql', graphqlHTTP({
    schema: stitchedSchema,
    graphiql: true,
  }));

  app.listen(4000, () => console.log('Gateway server running on http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Suorita palvelut

Sinun täytyy suorittaa käyttäjäpalvelu ja tuotepalvelu eri porteissa. Esimerkiksi:

Käyttäjäpalvelu (portti 4001):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4001, () => console.log('User service running on http://localhost:4001/graphql'));

Tuotepalvelu (portti 4002):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4002, () => console.log('Product service running on http://localhost:4002/graphql'));

4. Tee kysely yhdistettyyn skeemaan

Nyt voit tehdä kyselyn yhdistettyyn skeemaan yhdyskäytävän kautta (joka toimii portissa 4000). Voit suorittaa seuraavanlaisen kyselyn:


query {
  product(id: "101") {
    id
    name
    price
    user {
      id
      name
      email
    }
  }
}

Tämä kysely noutaa tuotteen, jonka ID on "101", ja hakee myös siihen liittyvän käyttäjän käyttäjäpalvelusta, osoittaen, miten Schema Stitching mahdollistaa datan hakemisen useista palveluista yhdellä pyynnöllä.

Edistyneet Schema Stitching -tekniikat

Perusesimerkin lisäksi tässä on joitakin edistyneitä tekniikoita, joita voidaan käyttää Schema Stitching -toteutuksen parantamiseen:

Schema Stitchingin ja Apollo Federationin välillä valitseminen

Vaikka Schema Stitching on toimiva vaihtoehto GraphQL-federaatiolle, Apollo Federationista on tullut suositumpi valinta sen edistyneiden ominaisuuksien ja parantuneen kehittäjäkokemuksen vuoksi. Tässä on vertailu näistä kahdesta lähestymistavasta:

Ominaisuus Schema Stitching Apollo Federation
Skeeman määrittely Käyttää olemassa olevaa GraphQL-skeemakieltä Käyttää deklaratiivista skeemakieltä direktiiveillä
Kyselyn suunnittelu Vaatii manuaalista kyselyn delegointia Automaattinen kyselyn suunnittelu Apollo Gatewayn toimesta
Tyyppien laajennukset Rajoitettu tuki Sisäänrakennettu tuki tyyppien laajennuksille
Avaindirektiivit Ei tuettu Käyttää @key-direktiiviä entiteettien tunnistamiseen
Hajautettu jäljitys Vaatii manuaalisen toteutuksen Sisäänrakennettu tuki hajautetulle jäljitykselle
Työkalut ja ekosysteemi Vähemmän kypsät työkalut Kypsemmät työkalut ja suuri yhteisö
Monimutkaisuus Voi olla monimutkaista hallita suurissa järjestelmissä Suunniteltu suuriin ja monimutkaisiin järjestelmiin

Milloin valita Schema Stitching:

Milloin valita Apollo Federation:

Tosielämän esimerkkejä ja käyttötapauksia

Tässä on joitakin tosielämän esimerkkejä siitä, miten GraphQL-federaatiota, mukaan lukien Schema Stitching, voidaan käyttää:

Parhaat käytännöt Schema Stitchingiin

Varmistaaksesi onnistuneen Schema Stitching -toteutuksen, noudata näitä parhaita käytäntöjä:

Yhteenveto

GraphQL-federaatio ja Schema Stitching tarjoavat tehokkaan lähestymistavan yhtenäisten API:iden rakentamiseen useista palveluista mikropalveluarkkitehtuurissa. Ymmärtämällä sen ydinajatukset, edut, rajoitukset ja toteutustekniikat, voit hyödyntää Schema Stitchingiä yksinkertaistaaksesi datan käyttöä, parantaaksesi skaalautuvuutta ja tehostaaksesi ylläpidettävyyttä. Vaikka Apollo Federation on noussut edistyneemmäksi ratkaisuksi, Schema Stitching on edelleen varteenotettava vaihtoehto yksinkertaisemmissa tapauksissa tai integroidessa olemassa olevia GraphQL-palveluita. Harkitse huolellisesti erityistarpeitasi ja vaatimuksiasi valitaksesi parhaan lähestymistavan organisaatiollesi.